/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			pgscript.cc
  \date			Dec 2011
  \author		TNick

  \brief		General purpose elements for the library


*//*

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read COPYING and README files in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<pgscript.h>
#include	<pgscript_internal.h>

#include	<session.h>

#include	<build-in/uvartree.h>
#include	<build-in/uvarstring.h>
#include	<build-in/uvarint.h>
#include	<build-in/uvardouble.h>
#include	<build-in/uvarcolor.h>
#include	<build-in/uvarchar.h>
#include	<build-in/uvarbool.h>
#include	<build-in/uvarary.h>

#include	<pgsave/ipgsave.h>


#include	<storetype.h>

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  DEFINITIONS    --------------------------------------------------------- */

using namespace PgScr;




/*  DEFINITIONS    ========================================================= */
//
//
//
//
/*  DATA    ---------------------------------------------------------------- */

DefVar **		PgScr::bldin_intf = NULL;

/**
*	@brief	list of callbacks for build in types
*
*	PgSave::IPgSave derived classes use a system of callbacks for creating
*	and loading values. The library creates a map of callbacks when is
*	initialise() d and that is the map that gets appended to existing
*	map in PgSave::IPgSave.
*/
QMap<QString, PgSave::IPgSave::KB_BLIND_LOAD>	kb_def_types;


/*  DATA    ================================================================ */
//
//
//
//
/*  FUNCTIONS    ----------------------------------------------------------- */

/* ------------------------------------------------------------------------- */
void			PgScr::initialise				( void )
{
	if ( Session::def_ss != NULL )
	{
		Q_ASSERT_X( false, "PgScript", "Initialisation of already initialised instance." );
		delete Session::def_ss;
	}
	Session::def_ss = new Session();

	Q_ASSERT( bldin_intf == NULL );
	bldin_intf = (DefVar **)malloc( sizeof(DefVar *) * VTY_DEFVAR );

	/* creating instances for build-in types */
	bldin_intf[ VTY_FLAG_ARRAY ] = new UVarAry();
	bldin_intf[ VTY_FLAG_TREE ] = new UVarTree();
	bldin_intf[ VTY_INTEGER ] = new UVarInt();
	bldin_intf[ VTY_BOOL ] = new UVarBool();
	bldin_intf[ VTY_CHARACTER ] = new UVarChar();
	bldin_intf[ VTY_COLOR ] = new UVarColor();
	bldin_intf[ VTY_DOUBLE ] = new UVarDouble();
	bldin_intf[ VTY_STRING ] = new UVarString();


	/* set-up a map of callbacks for build-in variables*/
	kb_def_types.insert(
				bldin_intf[ VTY_FLAG_ARRAY ]->typeName(),
				UVarAry::blindCreate );
	kb_def_types.insert(
				bldin_intf[ VTY_FLAG_TREE ]->typeName(),
				UVarTree::blindCreate );
	kb_def_types.insert(
				bldin_intf[ VTY_INTEGER ]->typeName(),
				UVarInt::blindCreate );
	kb_def_types.insert(
				bldin_intf[ VTY_BOOL ]->typeName(),
				UVarBool::blindCreate );
	kb_def_types.insert(
				bldin_intf[ VTY_CHARACTER ]->typeName(),
				UVarChar::blindCreate );
	kb_def_types.insert(
				bldin_intf[ VTY_COLOR ]->typeName(),
				UVarColor::blindCreate );
	kb_def_types.insert(
				bldin_intf[ VTY_DOUBLE ]->typeName(),
				UVarDouble::blindCreate );
	kb_def_types.insert(
				bldin_intf[ VTY_STRING ]->typeName(),
				UVarString::blindCreate );


}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void			PgScr::terminate				( void )
{

	Q_ASSERT( Session::def_ss != NULL );
	delete Session::def_ss;
	Session::def_ss = NULL;

	Q_ASSERT( bldin_intf != NULL );
	for ( int i = 0; i < VTY_DEFVAR; i++ )
	{
		delete bldin_intf[i];
	}
	delete bldin_intf;

	kb_def_types.clear();
}
/* ========================================================================= */


/* ------------------------------------------------------------------------- */
Session*		PgScr::createSession			( void )
{
	Session * new_ss = new Session();

	return new_ss;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
Session *		PgScr::currentSession			( void )
{
	return Session::def_ss;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void			PgScr::deleteSession			( Session * targ_ss )
{
	if ( Session::def_ss == targ_ss )
	{
		Q_ASSERT_X(  false, "PgScript", "Attempt to delete default session" );
		return;
	}

	delete targ_ss;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void			PgScr::makeSessionCurrent		( Session * targ_ss )
{
	if ( Session::def_ss != targ_ss )
	{
		Session::def_ss = targ_ss;
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void			PgScr::bInSaveKb				( PgSave::IPgSave& targ_i )
{
	targ_i.uniteKb( kb_def_types );
}
/* ========================================================================= */


/* ------------------------------------------------------------------------- */
void			PgScr::saveSessionList (
		QString s_name, Session ** p_array, int cnt,
		PgSave::IPgSave& targ_i )
{
	targ_i.setPath( s_name );

	for ( int i = 0; i < cnt; i++ )
	{
		saveSession(QString::number( i ), p_array[i], targ_i );
	}

	targ_i.cdUp();
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void			PgScr::saveSessionList (
		QString s_name, QList<Session *> & p_array,
		PgSave::IPgSave& targ_i )
{
	targ_i.setPath( s_name );

	for ( int i = 0; i < p_array.count(); i++ )
	{
		saveSession(QString::number( i ), p_array.at( i ), targ_i );
	}

	targ_i.cdUp();
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void			PgScr::saveSession (
		QString s_name, Session * ses, PgSave::IPgSave& targ_i )
{

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
Session **		PgScr::loadSessionList (
		int & cnt, PgSave::IPgSave& targ_i )
{

	int i_alloc = 32;

	Session **			p_ary;
	Session **			p_ary_tmp;
	p_ary = (Session **) malloc( sizeof(Session *) * i_alloc );
	Q_ASSERT( p_ary != NULL );

	int i = 0;
	while ( i < MAX_COMPONENTS_COUNT )
	{
		/* enshure a large enough array */
		if ( i == i_alloc )
		{
			i_alloc += 32;
			p_ary_tmp = (Session **) realloc(
						p_ary, sizeof(Session *) * i_alloc );
			Q_ASSERT( p_ary_tmp != NULL );
			p_ary_tmp = p_ary;
		}

		QString	s_crt = QString::number( i );
		if ( ! targ_i.exists( s_crt + "/" + SESSION_NAME ) )
			break;

		p_ary[i] = loadSession( s_crt, targ_i );

		i++;
	}

	cnt = i;
	if ( i == 0 )
	{
		free( p_ary );
		return NULL;
	}
	else
	{
		if ( i != i_alloc )
		{
			p_ary_tmp = (Session **) realloc(
						p_ary, sizeof(Session *) * i );
			Q_ASSERT( p_ary_tmp != NULL );
			p_ary_tmp = p_ary;
		}
		return p_ary;
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void			PgScr::loadSessionList (
		QList<Session *> & p_array, PgSave::IPgSave &targ_i )
{

	int i = 0;
	while ( i < MAX_COMPONENTS_COUNT )
	{

		QString	s_crt = QString::number( i );
		if ( ! targ_i.exists( s_crt + "/" + SESSION_NAME ) )
			break;

		p_array.append( loadSession( s_crt, targ_i ) );

		i++;
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
Session *		PgScr::loadSession (
		QString s_name, PgSave::IPgSave& targ_i )
{

}
/* ========================================================================= */



/*  FUNCTIONS    =========================================================== */
//
//
//
//
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
